package com.soulkun.smarthome.ui.main.personal

import android.app.Service
import android.os.Bundle
import android.view.MotionEvent
import android.view.View
import android.view.inputmethod.InputMethodManager
import androidx.core.content.res.ResourcesCompat
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import androidx.navigation.navGraphViewModels
import androidx.recyclerview.widget.LinearLayoutManager
import com.amap.api.maps.AMap
import com.amap.api.maps.CameraUpdateFactory
import com.amap.api.maps.MapsInitializer
import com.amap.api.maps.model.LatLng
import com.amap.api.maps.model.MyLocationStyle
import com.amap.api.services.core.AMapException
import com.amap.api.services.core.LatLonPoint
import com.amap.api.services.geocoder.*
import com.amap.api.services.help.Inputtips
import com.amap.api.services.help.InputtipsQuery
import com.soulkun.smarthome.R
import com.soulkun.smarthome.databinding.AppFragmentMainPersonalFamilyLocationBinding
import com.soulkun.smarthome.databinding.AppRecycleItemMainPersonalFamilyLocationSearchListBinding
import com.soulkun.smarthome.logic.enum.NavigationEnum
import com.soulkun.smarthome.logic.model.AddressModel
import com.soulkun.smarthome.ui.main.personal.adapter.AppMainPersonalFamilyLocationSearchListAdapter
import com.soulkun.smarthome.ui.main.personal.viewmodel.AppMainPersonalFamilyCreateViewModel
import com.soulkun.smarthome.ui.main.personal.viewmodel.AppMainPersonalFamilyLocationViewModel
import soulkun.library.mvvm.adapter.clearAndAddAll
import soulkun.library.mvvm.component.BaseDataBindingFragment
import soulkun.library.utils.screen.ScreenUtils

class AppMainPersonalFamilyCreateLocationFragment :
    BaseDataBindingFragment<AppFragmentMainPersonalFamilyLocationBinding>() {

    private val createViewModel by navGraphViewModels<AppMainPersonalFamilyCreateViewModel>(R.id.app_navigation_family_create)
    private val viewModel by viewModels<AppMainPersonalFamilyLocationViewModel> { defaultViewModelProviderFactory }

    private lateinit var aMap: AMap
    private lateinit var geocodeSearch: GeocodeSearch

    private val inputTipsListener by lazy {
        Inputtips.InputtipsListener { tipList, rCode ->
            if (rCode == AMapException.CODE_AMAP_SUCCESS) {
                viewModel.searchList.clearAndAddAll(tipList.map {
                    AddressModel(it.name, it.point)
                })
            }
        }
    }

    private val adapter by lazy {
        AppMainPersonalFamilyLocationSearchListAdapter(mContext, viewModel.searchList) { binding ->
            View.OnClickListener {
                viewModel.searchListShowStatusLiveData.value = false
                viewModel.searchAddressLiveData.value =
                    (binding as AppRecycleItemMainPersonalFamilyLocationSearchListBinding).addressModel!!
                viewModel.locationStatusLiveData.value =
                    AppMainPersonalFamilyLocationViewModel.LocationStatus.Search
                requireDataBinding().etMainPersonalFamilyLocationTextSearch.clearFocus()
                val inputMethodManager =
                    mContext.getSystemService(Service.INPUT_METHOD_SERVICE) as InputMethodManager
                if (inputMethodManager.isActive) {
                    inputMethodManager.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0)
                }
            }
        }
    }

    override fun setLayout(): Int {
        return R.layout.app_fragment_main_personal_family_location
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        initMap(savedInstanceState)
        super.onViewCreated(view, savedInstanceState)
    }

    override fun initView() {
        if (createViewModel.navigationEnum == NavigationEnum.Main){
            ScreenUtils.setViewFitSystemWindows(requireDataBinding().root)
        }
        requireDataBinding().rvMainPersonalFamilyLocationListSearch.run {
            layoutManager = LinearLayoutManager(mContext)
            adapter = this@AppMainPersonalFamilyCreateLocationFragment.adapter
        }
    }

    override fun initData() {
        requireDataBinding().lifecycleOwner = viewLifecycleOwner
        requireDataBinding().viewModel = viewModel
        requireDataBinding().onClickListener = View.OnClickListener {
            when (it.id) {
                R.id.iv_main_personal_family_location_icon_back -> {
                    findNavController().navigateUp()
                }
                R.id.tv_main_personal_family_location_text_submit -> {
                    createViewModel.familyLocationLiveData.value = viewModel.familyLocationLatLngLiveData.value
                    findNavController().navigateUp()
                }
                R.id.iv_main_personal_family_location_icon_search_back -> {
                    if (requireDataBinding().etMainPersonalFamilyLocationTextSearch.isFocused) {
                        viewModel.searchListShowStatusLiveData.value = false
                        requireDataBinding().etMainPersonalFamilyLocationTextSearch.clearFocus()
                        val inputMethodManager =
                            mContext.getSystemService(Service.INPUT_METHOD_SERVICE) as InputMethodManager
                        if (inputMethodManager.isActive) {
                            inputMethodManager.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0)
                        }
                    }
                }
                R.id.iv_main_personal_family_location_icon_delete -> {
                    viewModel.searchEditLiveData.value = ""
                }
                R.id.iv_main_personal_family_location_icon_current -> {
                    viewModel.locationStatusLiveData.value =
                        AppMainPersonalFamilyLocationViewModel.LocationStatus.Current
                }
            }
        }
    }

    override fun initListener() {
        // 设置地图加载
        aMap.addOnMapLoadedListener {
            aMap.showBuildings(false)
            aMap.showIndoorMap(false)
        }
        // 经纬度监听器
        aMap.setOnMyLocationChangeListener { location ->
            viewModel.currentLatLngLiveData.value = LatLng(location.latitude, location.longitude)
            if (viewModel.initLocation) {
                viewModel.locationStatusLiveData.value =
                    AppMainPersonalFamilyLocationViewModel.LocationStatus.Current
                viewModel.initLocation = false
            }
        }
        // 地图手势监听器
        aMap.setOnMapTouchListener {
            when (it.action) {
                MotionEvent.ACTION_DOWN -> {
                    viewModel.locationStatusLiveData.value =
                        AppMainPersonalFamilyLocationViewModel.LocationStatus.Move
                }
                MotionEvent.ACTION_UP -> {
                    viewModel.locationStatusLiveData.value =
                        AppMainPersonalFamilyLocationViewModel.LocationStatus.Center
                }
            }
        }
        // 位置搜索监听
        geocodeSearch.setOnGeocodeSearchListener(object : GeocodeSearch.OnGeocodeSearchListener {
            // 经纬度转位置名称
            override fun onRegeocodeSearched(result: RegeocodeResult?, rCode: Int) {
                if (rCode == AMapException.CODE_AMAP_SUCCESS) {
                    if (result != null && result.regeocodeAddress != null && result.regeocodeAddress.formatAddress != null) {
                        val locationText = result.regeocodeAddress.formatAddress
                        viewModel.locationTextLiveData.value = locationText
                        viewModel.searchEditLiveData.value = locationText
                        if (viewModel.locationStatusLiveData.value == AppMainPersonalFamilyLocationViewModel.LocationStatus.Current) {
                            viewModel.currentCity = result.regeocodeAddress.city
                        }
                    }
                }
            }

            // 位置名称转经纬度
            override fun onGeocodeSearched(result: GeocodeResult?, rCode: Int) {
//                if (rCode == AMapException.CODE_AMAP_SUCCESS) {
//                    if (result != null && result.geocodeAddressList != null && result.geocodeAddressList.size > 0) {
//                        val latLon = LatLng(
//                            result.geocodeAddressList[0].latLonPoint.latitude,
//                            result.geocodeAddressList[0].latLonPoint.longitude
//                        )
//                        aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLon, 17f))
//                        viewModel.locationTextLiveData.value =
//                            viewModel.searchAddressLiveData.value ?: ""
//                        viewModel.searchEditLiveData.value =
//                            viewModel.searchAddressLiveData.value ?: ""
//                    } else {
//                        "暂无结果".toast()
//                    }
//                } else {
//                    "查询出错".toast()
//                }
            }

        })
        // 搜索监听
        requireDataBinding().etMainPersonalFamilyLocationTextSearch.run {
            setOnFocusChangeListener { _, hasFocus ->
                viewModel.searchListShowStatusLiveData.value = hasFocus
                requireDataBinding().ivMainPersonalFamilyLocationIconSearchBack.setImageDrawable(
                    ResourcesCompat.getDrawable(
                        resources,
                        if (hasFocus) R.drawable.app_main_personal_family_location_icon_back else R.drawable.app_main_personal_family_location_icon_search,
                        null
                    )
                )
            }
        }
        // 输入监听
        viewModel.searchEditLiveData.observe(viewLifecycleOwner) {
            if (it != "") {
                val inputTipsQuery = InputtipsQuery(it, viewModel.currentCity)
                val inputTips = Inputtips(mContext, inputTipsQuery)
                inputTips.setInputtipsListener(inputTipsListener)
                inputTips.requestInputtipsAsyn()
            } else {
                viewModel.searchList.clear()
            }
        }
        // 位置状态监听
        viewModel.locationStatusLiveData.observe(viewLifecycleOwner) {
            when (it) {
                AppMainPersonalFamilyLocationViewModel.LocationStatus.Current -> {
                    if (viewModel.currentLatLngLiveData.value != null) {
                        val currentLocation = viewModel.currentLatLngLiveData.value!!
                        viewModel.familyLocationLatLngLiveData.value = currentLocation
                        geocodeSearch.getFromLocationAsyn(
                            RegeocodeQuery(
                                LatLonPoint(
                                    currentLocation.latitude,
                                    currentLocation.longitude
                                ), 100f, GeocodeSearch.AMAP
                            )
                        )
                        aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLocation, 17f))
                    }
                }
                AppMainPersonalFamilyLocationViewModel.LocationStatus.Center -> {
                    val latLng = aMap.cameraPosition.target
                    viewModel.familyLocationLatLngLiveData.value = latLng
                    geocodeSearch.getFromLocationAsyn(
                        RegeocodeQuery(
                            LatLonPoint(
                                latLng.latitude,
                                latLng.longitude
                            ), 100f, GeocodeSearch.AMAP
                        )
                    )
                }
                AppMainPersonalFamilyLocationViewModel.LocationStatus.Move -> {
                    viewModel.locationTextLiveData.value = "搜索地址中..."
                    viewModel.searchEditLiveData.value = "搜索地址中..."
                }
                AppMainPersonalFamilyLocationViewModel.LocationStatus.Search -> {
                    viewModel.locationTextLiveData.value =
                        viewModel.searchAddressLiveData.value!!.formatAddress
                    viewModel.searchEditLiveData.value =
                        viewModel.searchAddressLiveData.value!!.formatAddress
                    val latLng = LatLng(
                        viewModel.searchAddressLiveData.value!!.latLngPoint.latitude,
                        viewModel.searchAddressLiveData.value!!.latLngPoint.longitude
                    )
                    viewModel.familyLocationLatLngLiveData.value = latLng
                    aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 17f))
                }
            }
        }
    }

    override fun doOnCreate() {
    }

    private fun initMap(savedInstanceState: Bundle?) {
        MapsInitializer.updatePrivacyShow(mContext, true, true)
        MapsInitializer.updatePrivacyAgree(mContext, true)
        requireDataBinding().mvMainPersonalFamilyLocationMap.onCreate(savedInstanceState)
        aMap = requireDataBinding().mvMainPersonalFamilyLocationMap.map
        aMap.uiSettings.run {
            // 设置默认定位按钮是否显示
            isMyLocationButtonEnabled = false
            // 设置地图缩放按钮不显示
            isZoomControlsEnabled = false
            // 设置地图比例尺显示
            isScaleControlsEnabled = true
        }
        // 设置为true表示显示定位层并可触发定位，false表示隐藏定位层并不可触发定位，默认是false
        aMap.isMyLocationEnabled = true
        // 自定义系统定位蓝点
        val myLocationStyle = MyLocationStyle()
        // 设置不显示定位蓝点
        myLocationStyle.showMyLocation(false)
        // 设置定位频率
        myLocationStyle.interval(5000)
        // 将自定义的 myLocationStyle 对象添加到地图上
        aMap.myLocationStyle = myLocationStyle
        geocodeSearch = GeocodeSearch(mContext)
    }

    override fun onResume() {
        super.onResume()
        requireDataBinding().mvMainPersonalFamilyLocationMap.onResume()
    }

    override fun onPause() {
        super.onPause()
        requireDataBinding().mvMainPersonalFamilyLocationMap.onPause()
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        requireDataBinding().mvMainPersonalFamilyLocationMap.onSaveInstanceState(outState)
    }

    override fun onDestroyView() {
        requireDataBinding().mvMainPersonalFamilyLocationMap.onDestroy()
        super.onDestroyView()
    }

}